#include "StrDiff.h"
#include "TestWorkModeMenuText.h"
#include <cassert>
#include <iostream>

namespace TestWorkModeMenuText
{

/////////////////////////////////////////////////////////////////////////////////////////////////////

void RunAllTests ()
{
	TestInvalidSelection::Run ();
	TestValidSelection::Run ();
	TestMenuItems::Run ();
}

/////////////////////////////////////////////////////////////////////////////////////////////////////

TestBase::TestBase ()
{
	receiver = WorkModeReceiverFake::Spawn ();
	textStream = TextStreamFake::Spawn ();
}

TestBase::~TestBase ()
{
	textStream.Delete ();
	receiver.Delete ();
}

std::string TestBase::SuiteIdentity ()
{
	return "TestWorkModeMenuText";
}

void TestBase::RunSingle ()
{
	WorkModeMenuTextLocalizationInterfacePtr menuLocalization = WorkModeMenuTextLocalizationFake::Spawn ();
	WorkModeMenuInterfacePtr menuText ( WorkModeMenuText::Spawn ( menuLocalization, textStream ) );
	
	menuText->Run ( receiver );
	
	menuText.Delete ();
	menuLocalization.Delete ();
	
	CheckOutput ();
}

void TestBase::CheckOutput ()
{
	std::string actualOutput = textStream->written;
	if ( actualOutput != expectedOutput )
	{
		std::cout << StrDiff ( actualOutput, expectedOutput );
		std::cout << " != " << "\n\r";
		std::cout << StrDiff ( expectedOutput, actualOutput );
		std::cout << "\n\r";	
	}
	TEST_ASSUMPTION ( actualOutput == expectedOutput );
}

/////////////////////////////////////////////////////////////////////////////////////////////////////

TestInvalidSelection::TestInvalidSelection ()
{
	textStream->readChars =
		  std::string ( "Z" )
		+ std::string ( "X" )
		+ std::string ( 1, WorkModeMenuTextLocalizationFake::SELECTION_CREATE_NEW )
		;
	expectedOutput = 
		  WorkModeMenuTextLocalizationFake::MENU
		+ WorkModeMenuTextLocalizationFake::INPUT_WELCOME
		+ "Z\n\r"
		+ WorkModeMenuTextLocalizationFake::INVALID_SELECTION
		+ WorkModeMenuTextLocalizationFake::INPUT_WELCOME
		+ "X\n\r"
		+ WorkModeMenuTextLocalizationFake::INVALID_SELECTION
		+ WorkModeMenuTextLocalizationFake::INPUT_WELCOME
		+ std::string ( 1, WorkModeMenuTextLocalizationFake::SELECTION_CREATE_NEW )
		+ "\n\r"
		;
}

std::string TestInvalidSelection::TestIdentity ()
{
	return "TestInvalidSelection";
}

void TestInvalidSelection::Run ()
{
	TestInvalidSelection ().RunSingle ();
}

/////////////////////////////////////////////////////////////////////////////////////////////////////

TestValidSelection::TestValidSelection ()
{
	textStream->readChars = std::string ( 1, WorkModeMenuTextLocalizationFake::SELECTION_CREATE_NEW );
	expectedOutput = 
		  WorkModeMenuTextLocalizationFake::MENU
		+ WorkModeMenuTextLocalizationFake::INPUT_WELCOME
		+ std::string ( 1, WorkModeMenuTextLocalizationFake::SELECTION_CREATE_NEW )
		+ "\n\r"
		;
}

std::string TestValidSelection::TestIdentity ()
{
	return "TestValidSelection";
}

void TestValidSelection::Run ()
{
	TestValidSelection ().RunSingle ();
}

/////////////////////////////////////////////////////////////////////////////////////////////////////

TestMenuItems::TestMenuItems ( std::string argReceiverFunctionInvoked, char argMenuSelection )
: receiverFunctionInvoked ( argReceiverFunctionInvoked )
, menuSelection ( argMenuSelection )
{
	textStream->readChars = std::string ( 1, menuSelection );
	expectedOutput = 
		  WorkModeMenuTextLocalizationFake::MENU
		+ WorkModeMenuTextLocalizationFake::INPUT_WELCOME
		+ std::string ( 1, menuSelection )
		+ "\n\r"
		;
}

TestMenuItems::~TestMenuItems ()
{
	TEST_ASSUMPTION ( receiver->callHistory.size () == 1 );
	TEST_ASSUMPTION ( receiver->callHistory [ 0 ] == receiverFunctionInvoked );
}

std::string TestMenuItems::TestIdentity ()
{
	return "TestMenuItems : "
		"receiverFunctionInvoked = \"" + receiverFunctionInvoked + "\", "
		"menuSelection = \"" + std::string ( 1, menuSelection ) + "\""
		;
}

void TestMenuItems::Run ()
{
	TestMenuItems ( WorkModeReceiverFake::CREATE_NEW             , WorkModeMenuTextLocalizationFake::SELECTION_CREATE_NEW             ).RunSingle ();
	TestMenuItems ( WorkModeReceiverFake::OPEN_EXISTING          , WorkModeMenuTextLocalizationFake::SELECTION_OPEN_EXISTING          ).RunSingle ();
	TestMenuItems ( WorkModeReceiverFake::CHANGE_DESIGNATION     , WorkModeMenuTextLocalizationFake::SELECTION_CHANGE_DESIGNATION     ).RunSingle ();
	TestMenuItems ( WorkModeReceiverFake::MAKE_COPY              , WorkModeMenuTextLocalizationFake::SELECTION_MAKE_COPY              ).RunSingle ();
	TestMenuItems ( WorkModeReceiverFake::QUIT                   , WorkModeMenuTextLocalizationFake::SELECTION_QUIT                   ).RunSingle ();
	TestMenuItems ( WorkModeReceiverFake::DELETE_TO_TRASH_CAN    , WorkModeMenuTextLocalizationFake::SELECTION_DELETE_TO_TRASH_CAN    ).RunSingle ();
	TestMenuItems ( WorkModeReceiverFake::RESTORE_FROM_TRASH_CAN , WorkModeMenuTextLocalizationFake::SELECTION_RESTORE_FROM_TRASH_CAN ).RunSingle ();
	TestMenuItems ( WorkModeReceiverFake::EXTRACT_FROM_PACKAGE   , WorkModeMenuTextLocalizationFake::SELECTION_EXTRACT_FROM_PACKAGE   ).RunSingle ();
	TestMenuItems ( WorkModeReceiverFake::IMPORT_FROM_FOX_PRO    , WorkModeMenuTextLocalizationFake::SELECTION_IMPORT_FROM_FOX_PRO    ).RunSingle ();
	TestMenuItems ( WorkModeReceiverFake::IMPORT_FROM_ORACLE     , WorkModeMenuTextLocalizationFake::SELECTION_IMPORT_FROM_ORACLE     ).RunSingle ();
}

/////////////////////////////////////////////////////////////////////////////////////////////////////

}; // namespace TestWorkModeMenuText
